package com.yck12.v1;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import net.sourceforge.pinyin4j.PinyinHelper;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Main {

    public static void main(String[] args) throws IOException {
        //建立多人的中文姓名的列表，每个人占用一行，有四列，支持四种拼音名称，例如 郭立新,转换为：guo lixin, guo lx, guo lixin, guo lx
        List<String> chineseNames = Arrays.asList(
                "周志光", "朱敏", "翁建平", "纪立农", "郭立新", "杨涛", "傅君芬", "罗小平", "朱大龙", "赵家军", "母义明", "王天佑", "王卫庆", "洪天配", "宁光", "贾伟平", "肖建中", "严励", "严德文", "毕艳", "杨金奎", "杨昱", "余学锋", "曾天舒", "张弛", "张惠杰", "张丽辉", "张秋", "郑超", "周家强", "周健", "蔡梦茵", "陈莉", "陈黎明", "陈临琪", "董关平", "杜建玲", "龚春秀", "纪秋和", "姜宏伟", "姜生", "匡洪宇", "匡健", "雷闽湘", "李玲", "李频", "李启富", "李霞", "李小英", "李延兵", "李益明", "苏哲", "罗飞宏"
        );

        List<String> names = new ArrayList<>();
        for (String chineseName : chineseNames) {
            // 使用pinyin4j将中文姓名转换为拼音
            String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(chineseName.charAt(0));
            String firstName = pinyinArray[0].replaceAll("\\d", "");
            String lastName = chineseName.substring(1);
            String[] lastNamePinyinArray = PinyinHelper.toHanyuPinyinStringArray(lastName.charAt(0));
            String lastNamePinyin = lastNamePinyinArray[0].replaceAll("\\d", "");

            // 生成四种拼音格式
            String format1 = firstName + " " + lastNamePinyin;
            String format2 = firstName + " " + lastNamePinyin.substring(0, 1);
            String format3 = format1;
            String format4 = format2;

            names.add(format1 + "," + format2 + "," + format3 + "," + format4);
        }
        System.out.println(names);

        for (String name : names) {
            String outputFile = "query_results.txt";
            String[] parts = name.split(",");
//            String strName = String.format("AND ((((%s[Author - First]) OR (%s[Author - First])) OR (%s[Author - First])) OR (%s[Author - First])) AND (y_5[Filter])",
//                    parts[0], parts[1], parts[2], parts[3]);
//            String strName = String.format("AND ((((%s[Author]) OR (%s[Author])) OR (%s[Author])) OR (%s[Author])) AND (y_5[Filter])",
//                    parts[0], parts[1], parts[2], parts[3]);
//            String strName = String.format(" AND ((((%s[Author - Last]) OR (%s[Author - Last])) OR (%s[Author - Last])) OR (%s[Author - Last])) AND (y_5[Filter])",
//                    parts[0], parts[1], parts[2], parts[3]);
//            String strName = String.format("AND ((((%s[Author]) OR (%s[Author])) OR (%s[Author])) OR (%s[Author])) AND (y_5[Filter]) AND (clinicaltrial[Filter])",
//                parts[0], parts[1], parts[2], parts[3]);
//            String  query= "((((((((((((((((((((((((((((((\"Diabetes Mellitus, Type 1\"[Mesh]) OR (Type 1 Diabetes[Title/Abstract])) OR (Diabetes, Type 1[Title/Abstract])) OR (Diabetes Mellitus, Insulin-Dependent[Title/Abstract])) OR (Diabetes Mellitus, Insulin Dependent[Title/Abstract])) OR (Insulin-Dependent Diabetes Mellitus[Title/Abstract])) OR (Diabetes Mellitus, Juvenile-Onset[Title/Abstract])) OR (Diabetes Mellitus, Juvenile Onset[Title/Abstract])) OR (Juvenile-Onset Diabetes Mellitus[Title/Abstract])) OR (IDDM[Title/Abstract])) OR (Diabetes Mellitus, Type I[Title/Abstract])) OR (Diabetes Mellitus, Sudden-Onset[Title/Abstract])) OR (Diabetes Mellitus, Sudden Onset[Title/Abstract])) OR (Sudden-Onset Diabetes Mellitus[Title/Abstract])) OR (Type 1 Diabetes Mellitus[Title/Abstract])) OR (Diabetes Mellitus, Insulin-Dependent, 1[Title/Abstract])) OR (Insulin-Dependent Diabetes Mellitus 1[Title/Abstract])) OR (Insulin Dependent Diabetes Mellitus 1[Title/Abstract])) OR (Juvenile-Onset Diabetes[Title/Abstract])) OR (Diabetes, Juvenile-Onset[Title/Abstract])) OR (Juvenile Onset Diabetes[Title/Abstract])) OR (Diabetes, Autoimmune[Title/Abstract])) OR (Autoimmune Diabetes[Title/Abstract])) OR (Diabetes Mellitus, Brittle[Title/Abstract])) OR (Brittle Diabetes Mellitus[Title/Abstract])) OR (Diabetes Mellitus, Ketosis-Prone[Title/Abstract])) OR (Diabetes Mellitus, Ketosis Prone[Title/Abstract])) OR (Ketosis-Prone Diabetes Mellitus[Title/Abstract]))) OR ((((\"Thyroid Diseases\"[Mesh]) OR (Diseases, Thyroid[Title/Abstract])) OR (Disease, Thyroid[Title/Abstract])) OR (Thyroid Disease[Title/Abstract])))";
//            String  query=" ((((((\"Thyroid Diseases\"[Mesh]) OR (Diseases, Thyroid[Title/Abstract])) OR (Disease, Thyroid[Title/Abstract])) OR (Thyroid Disease[Title/Abstract])) OR (((((((((((((((((((((((((((((\"Diabetes Mellitus, Type 1\"[Mesh]) OR (Type 1 Diabetes[Title/Abstract])) OR (Diabetes, Type 1[Title/Abstract])) OR (Diabetes Mellitus, Insulin-Dependent[Title/Abstract])) OR (Diabetes Mellitus, Insulin Dependent[Title/Abstract])) OR (Insulin-Dependent Diabetes Mellitus[Title/Abstract])) OR (Diabetes Mellitus, Juvenile-Onset[Title/Abstract])) OR (Diabetes Mellitus, Juvenile Onset[Title/Abstract])) OR (Juvenile-Onset Diabetes Mellitus[Title/Abstract])) OR (IDDM[Title/Abstract])) OR (Diabetes Mellitus, Type I[Title/Abstract])) OR (Diabetes Mellitus, Sudden-Onset[Title/Abstract])) OR (Diabetes Mellitus, Sudden Onset[Title/Abstract])) OR (Sudden-Onset Diabetes Mellitus[Title/Abstract])) OR (Type 1 Diabetes Mellitus[Title/Abstract])) OR (Diabetes Mellitus, Insulin-Dependent, 1[Title/Abstract])) OR (Insulin-Dependent Diabetes Mellitus 1[Title/Abstract])) OR (Insulin Dependent Diabetes Mellitus 1[Title/Abstract])) OR (Juvenile-Onset Diabetes[Title/Abstract])) OR (Diabetes, Juvenile-Onset[Title/Abstract])) OR (Juvenile Onset Diabetes[Title/Abstract])) OR (Diabetes, Autoimmune[Title/Abstract])) OR (Autoimmune Diabetes[Title/Abstract])) OR (Diabetes Mellitus, Brittle[Title/Abstract])) OR (Brittle Diabetes Mellitus[Title/Abstract])) OR (Diabetes Mellitus, Ketosis-Prone[Title/Abstract])) OR (Diabetes Mellitus, Ketosis Prone[Title/Abstract])) OR (Ketosis-Prone Diabetes Mellitus[Title/Abstract]))))) ";
//            String  searchTerm = query+strName;
            String searchTerm = String.format("(((((\"Thyroid Diseases\"[Mesh]) OR (Diseases, Thyroid[Title/Abstract])) OR (Disease, Thyroid[Title/Abstract])) OR (Thyroid Disease[Title/Abstract])) OR (((((((((((((((((((((((((((\"Diabetes Mellitus, Type 1\"[Mesh]) OR (Type 1 Diabetes[Title/Abstract])) OR (Diabetes, Type 1[Title/Abstract])) OR (Diabetes Mellitus, Insulin-Dependent[Title/Abstract])) OR (Diabetes Mellitus, Insulin Dependent[Title/Abstract])) OR (Insulin-Dependent Diabetes Mellitus[Title/Abstract])) OR (Diabetes Mellitus, Juvenile-Onset[Title/Abstract])) OR (Diabetes Mellitus, Juvenile Onset[Title/Abstract])) OR (Juvenile-Onset Diabetes Mellitus[Title/Abstract])) OR (IDDM[Title/Abstract])) OR (Diabetes Mellitus, Type I[Title/Abstract])) OR (Diabetes Mellitus, Sudden-Onset[Title/Abstract])) OR (Diabetes Mellitus, Sudden Onset[Title/Abstract])) OR (Sudden-Onset Diabetes Mellitus[Title/Abstract])) OR (Type 1 Diabetes Mellitus[Title/Abstract])) OR (Diabetes Mellitus, Insulin-Dependent, 1[Title/Abstract])) OR ((Insulin-Dependent Diabetes Mellitus 1[Title/Abstract])) OR (Insulin Dependent Diabetes Mellitus 1[Title/Abstract])) OR (Juvenile-Onset Diabetes[Title/Abstract])) OR (Diabetes, Juvenile-Onset[Title/Abstract])) OR (Juvenile Onset Diabetes[Title/Abstract])) OR (Diabetes, Autoimmune[Title/Abstract])) OR (Autoimmune Diabetes[Title/Abstract])) OR (Diabetes Mellitus, Brittle[Title/Abstract])) OR (Brittle Diabetes Mellitus[Title/Abstract])) OR (Diabetes Mellitus, Ketosis-Prone[Title/Abstract])) OR (Diabetes Mellitus, Ketosis Prone[Title/Abstract])) OR (Diabetes Mellitus, Ketosis Prone[Title/Abstract]))) AND ((((\"%s\"[Author]) OR (\"%s\"[Author])) OR (\"%s\"[Author])) OR (\"%s\"[Author]))  AND (y_5[Filter]) ",
                    parts[0], parts[1], parts[2], parts[3]);

            System.out.println("name: " + parts[0]);
            System.out.println("查询字符串: " + searchTerm);
            System.out.println();
             String apiUrl = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi";
            try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
                // 第一步：搜索文献获取PMID列表（支持翻页）
                int retstart = 0;
                int retmax = 100; // 每页返回的最大记录数
                boolean hasMoreResults = true;
                List<String> allPmids = new ArrayList<>();
                JsonNode idListNode = null;
                while (hasMoreResults) {
                    String searchUrl = String.format("%s?db=pubmed&term=%s&retmode=json&retstart=%d&retmax=%d",
                            apiUrl,
                            java.net.URLEncoder.encode(searchTerm, "UTF-8"),
                            retstart,
                            retmax);

                    HttpGet searchRequest = new HttpGet(searchUrl);

                    try (CloseableHttpResponse searchResponse = httpClient.execute(searchRequest)) {
                        HttpEntity searchEntity = searchResponse.getEntity();

                        if (searchEntity != null) {
                            String searchResult = EntityUtils.toString(searchEntity);
                            ObjectMapper mapper = new ObjectMapper();
                            JsonNode rootNode = mapper.readTree(searchResult);

                            // 提取PMID列表
                            idListNode = rootNode.path("esearchresult").path("idlist");
                            if (idListNode.isArray() && idListNode.size() > 0) {
                                for (JsonNode idNode : idListNode) {
                                    String pmid = idNode.asText();
                                    allPmids.add(pmid);
                                }
                                retstart += retmax; // 更新起始位置
                            } else {
                                hasMoreResults = false; // 没有更多结果，退出循环
                            }
                        }
                    }
                }

                if (!allPmids.isEmpty()) {
                    System.out.println("找到的文献PMID列表:");
                    for (String pmid : allPmids) {
                        System.out.println("PMID: " + pmid);
                    }
                    System.out.println("共找到 " + allPmids.size() + " 篇文献");
                } else {
                    System.out.println("未找到匹配的文献");
                }
                        // 第4步：将查询结果保存到本地文件

                try (PrintWriter writer = new PrintWriter(new FileWriter(outputFile, true))) {
                    writer.println("姓名: " + name);
                    writer.println("查询字符串: " + searchTerm);
                    writer.println("PMID列表: " + allPmids.toString());
                    writer.println("合计: " + allPmids.size());
                    writer.println("----------------------------------");
                } catch (IOException e) {
                    System.err.println("保存文件时出错: " + e.getMessage());
                }
                // 第5步：如果PMID列表合计大于等于100，就使用新的字符串
                if (allPmids.size() >= 50) {

                    String newSearchTerm = String.format("(((((\"Thyroid Diseases\"[Mesh]) OR (Diseases, Thyroid[Title/Abstract])) OR (Disease, Thyroid[Title/Abstract])) OR (Thyroid Disease[Title/Abstract])) OR (((((((((((((((((((((((((((\"Diabetes Mellitus, Type 1\"[Mesh]) OR (Type 1 Diabetes[Title/Abstract])) OR (Diabetes, Type 1[Title/Abstract])) OR (Diabetes Mellitus, Insulin-Dependent[Title/Abstract])) OR (Diabetes Mellitus, Insulin Dependent[Title/Abstract])) OR (Insulin-Dependent Diabetes Mellitus[Title/Abstract])) OR (Diabetes Mellitus, Juvenile-Onset[Title/Abstract])) OR (Diabetes Mellitus, Juvenile Onset[Title/Abstract])) OR (Juvenile-Onset Diabetes Mellitus[Title/Abstract])) OR (IDDM[Title/Abstract])) OR (Diabetes Mellitus, Type I[Title/Abstract])) OR (Diabetes Mellitus, Sudden-Onset[Title/Abstract])) OR (Diabetes Mellitus, Sudden Onset[Title/Abstract])) OR (Sudden-Onset Diabetes Mellitus[Title/Abstract])) OR (Type 1 Diabetes Mellitus[Title/Abstract])) OR (Diabetes Mellitus, Insulin-Dependent, 1[Title/Abstract])) OR ((Insulin-Dependent Diabetes Mellitus 1[Title/Abstract])) OR (Insulin Dependent Diabetes Mellitus 1[Title/Abstract])) OR (Juvenile-Onset Diabetes[Title/Abstract])) OR (Diabetes, Juvenile-Onset[Title/Abstract])) OR (Juvenile Onset Diabetes[Title/Abstract])) OR (Diabetes, Autoimmune[Title/Abstract])) OR (Autoimmune Diabetes[Title/Abstract])) OR (Diabetes Mellitus, Brittle[Title/Abstract])) OR (Brittle Diabetes Mellitus[Title/Abstract])) OR (Diabetes Mellitus, Ketosis-Prone[Title/Abstract])) OR (Diabetes Mellitus, Ketosis Prone[Title/Abstract])) OR (Diabetes Mellitus, Ketosis Prone[Title/Abstract]))) AND ((((\"%s\"[Author]) OR (\"%s\"[Author]))))  AND (y_5[Filter])",
                            parts[0], parts[1]);

                    System.out.println("PMID数量超过100，使用新查询字符串: " + newSearchTerm);
                    // 重新执行搜索逻辑
                    retstart = 0;
                    hasMoreResults = true;
                    allPmids.clear();

                    while (hasMoreResults) {
                        String searchUrl = String.format("%s?db=pubmed&term=%s&retmode=json&retstart=%d&retmax=%d",
                                apiUrl,
                                java.net.URLEncoder.encode(newSearchTerm, "UTF-8"),
                                retstart,
                                retmax);

                        HttpGet searchRequest = new HttpGet(searchUrl);

                        try (CloseableHttpResponse searchResponse = httpClient.execute(searchRequest)) {
                            HttpEntity searchEntity = searchResponse.getEntity();

                            if (searchEntity != null) {
                                String searchResult = EntityUtils.toString(searchEntity);
                                ObjectMapper mapper = new ObjectMapper();
                                JsonNode rootNode = mapper.readTree(searchResult);

                                // 提取PMID列表
                                idListNode = rootNode.path("esearchresult").path("idlist");
                                if (idListNode.isArray() && idListNode.size() > 0) {
                                    for (JsonNode idNode : idListNode) {
                                        String pmid = idNode.asText();
                                        allPmids.add(pmid);
                                    }
                                    retstart += retmax; // 更新起始位置
                                } else {
                                    hasMoreResults = false; // 没有更多结果，退出循环
                                }
                            }
                        }
                    }

                    if (!allPmids.isEmpty()) {
                        System.out.println("新查询找到的文献PMID列表:");
                        for (String pmid : allPmids) {
                            System.out.println("PMID: " + pmid);
                        }
                        System.out.println("共找到 " + allPmids.size() + " 篇文献");
                    } else {
                        System.out.println("新查询未找到匹配的文献");
                    }
                    // 第5-2步：将查询结果保存到本地文件
                    try (PrintWriter writer = new PrintWriter(new FileWriter(outputFile, true))) {
                        writer.println("姓名(异常): " + name);
                        writer.println("查询字符串（优化后）: " + newSearchTerm);
                        writer.println("PMID列表: " + allPmids.toString());
                        writer.println("合计: " + allPmids.size());
                        writer.println("----------------------------------");
                    } catch (IOException e) {
                        System.err.println("保存文件时出错: " + e.getMessage());
                    }
                }

            }catch(IOException e) {
                System.err.println("网络请求时出错: " + e.getMessage());
                e.printStackTrace();
            }
        }
    }
}

